package com.sduept.nwld.dataserver.controller.equipment.assessment;

import com.alibaba.fastjson.JSONObject;
import com.sduept.bigdata.web.jsf.controller.AbstractController;
import com.sduept.cim.ledger.excetpion.ManagementUnitException;
import com.sduept.cim.ledger.model.ManagementUnitDict;
import com.sduept.cim.ledger.services.ManagementUnitService;
import com.sduept.permission.entity.PersonnelEntityBean;
import com.sduept.permission.manager.DepartManager;
import com.sduept.utils.PingYinUtil;
import org.apache.commons.lang3.StringUtils;
import org.primefaces.PrimeFaces;
import org.primefaces.event.NodeSelectEvent;
import org.primefaces.event.NodeUnselectEvent;
import org.primefaces.model.DefaultTreeNode;
import org.primefaces.model.TreeNode;
import org.springframework.beans.factory.annotation.Autowired;

import javax.annotation.PostConstruct;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.view.ViewScoped;
import javax.inject.Named;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
 * 添加互查项控制器
 * @author pengz
 *
 */
@Named
@ViewScoped
public class SetInspectionOtherItemController extends AbstractController{

	private static final long serialVersionUID = 6889228854699294190L;
	@Autowired
	private ManagementUnitService unitService;
	@Autowired
	private DepartManager orgService;
	/**
	 * 保存本次互查项信息，用于返回调用该弹窗的页面
	 * 保存的信息有：
	 * 1.派出专家分子公司
	 * 2.被检单位id
	 */
	private String inspectOtherItemData = "{}";
	/**
	 * 选择的检修范围名称
	 */
	private String selectedScopeId;
	/**
	 * 派出专家联系人
	 */
	private String inspectionScopePersonnel;
	/**
	 * 派出专家分子公司联系人电话
	 */
	private String inspectionScopePersonnelPhone;
	/**
	 * 所有的检修范围（分子公司）
	 */
	private List<ManagementUnitDict> allMaintenanceScopes = new ArrayList<ManagementUnitDict>();;
	/**
	 * key:检修范围id
	 * value：检修范围
	 */
	private Map<String,ManagementUnitDict> allMaintenanceScopesMap  = new HashMap<String, ManagementUnitDict>();
	/**
	 * key:检修范围id
	 * value:运维单位
	 */
	private Map<String,List<ManagementUnitDict>> scopeToMaintenanceManagements = new HashMap<String, List<ManagementUnitDict>>();;
	/**
	 * 被检单位选择树根节点
	 */
	private TreeNode root= new DefaultTreeNode();;
	/**
	 * 选中的被检单位节点
	 */
	private TreeNode[] selectedNodes;
	
	private List<InspectionScopeModel> models = new ArrayList<InspectionScopeModel>();
	private List<InspectionScopeModel> selectedModels = new ArrayList<InspectionScopeModel>();
	/**
	 * key:检修范围名称
	 * value：该检修范围下的人员
	 */
	private Map<String,List<PersonnelEntityBean>> scopeNameToPersonnels = new HashMap<String, List<PersonnelEntityBean>>();;
	/**
	 * key:运维单位+人员名称
	 * value:人员
	 */
	private Map<String,PersonnelEntityBean> personnelMap = new HashMap<String, PersonnelEntityBean>();
	
	@PostConstruct
	public void init() {
		initData();
		initRoot();
		initInspectionScopeModels();
	}
	/**
	 * 初始化inspectionScopeModels
	 */
	private void initInspectionScopeModels() {
		for(ManagementUnitDict scope : allMaintenanceScopes) {
			InspectionScopeModel model = new InspectionScopeModel();
			model.setInspectionScope(scope.getName());
			models.add(model);
		}
	}
	/**
	 * 从缓存或数据库中加载页面初始化所需数据
	 */
	private void initData() {
		try {
			allMaintenanceScopes = unitService.getAllMaintenanceScopes();
			for (ManagementUnitDict managementUnitDict : allMaintenanceScopes) {
				allMaintenanceScopesMap.put(managementUnitDict.getId(), managementUnitDict);
			}
			//所有的运维单位
			List<ManagementUnitDict> maintenanceManagements = unitService.getAllMaintenanceManagements();
			for(ManagementUnitDict managementUnitDict : maintenanceManagements) {
				if(allMaintenanceScopesMap.containsKey(managementUnitDict.getPid())) {
					if(scopeToMaintenanceManagements.containsKey(managementUnitDict.getPid())) {
						scopeToMaintenanceManagements.get(managementUnitDict.getPid()).add(managementUnitDict);
					}else {
						List<ManagementUnitDict> units = new ArrayList<ManagementUnitDict>();
						units.add(managementUnitDict);
						scopeToMaintenanceManagements.put(managementUnitDict.getPid(), units);
					}
				}
			}
		} catch (ManagementUnitException e) {
			e.printStackTrace();
		}
	}
	/**
	 * 初始化被检单位选择树
	 * 一级节点---南方电网
	 * 二级节点---检修范围
	 * 三级节点---运维单位
	 */
	private void initRoot() {
		try {
			String rootName = unitService.getManagementUnitRoot();
			DefaultTreeNode unitRoot = new DefaultTreeNode("root", rootName, root);
			for(String scopeId : scopeToMaintenanceManagements.keySet()) {
				DefaultTreeNode scopeNode = new DefaultTreeNode("scope", allMaintenanceScopesMap.get(scopeId), unitRoot);
				for(ManagementUnitDict unit : scopeToMaintenanceManagements.get(scopeId)) {
					new DefaultTreeNode("unit", unit, scopeNode);
				}
			}
			unitRoot.setExpanded(true);
		} catch (ManagementUnitException e) {
			e.printStackTrace();
		}
		
	}
	/**
	 * 
	 */
	public void onUserDialogReturn() {
		String userJson = getParameter("userJson");
		String className = getParameter("className");
		if(PersonnelEntityBean.class.getSimpleName().equals(className) && StringUtils.isNoneBlank(userJson) ){
			PersonnelEntityBean user = JSONObject.parseObject(userJson, PersonnelEntityBean.class);
//			DepartmentEntityBean group = user.getGroup();
			inspectionScopePersonnel = user.getName();
			inspectionScopePersonnelPhone = user.getTelephone();
    	}
	}
	/**
	 * 关闭弹窗并返回
	 */
	public void closeAndReturn() {
		if(selectedModels==null||selectedModels.isEmpty()) {
			alertErrorMessage("请选择派出分子公司！");
			return;
		}
		if(selectedNodes == null && selectedNodes.length == 0 ) {
			alertErrorMessage("请选择一个或多个被检单位！");
			return;
		} 
//		else {
//			boolean hasUnit = false;
//			for (TreeNode sn : selectedNodes) {
//				if("unit".equals(sn.getType())) {
//					hasUnit = true;
//				}
//			}
//			if(!hasUnit) {
//				alertErrorMessage("请选择一个或多个被检单位！");
//				return;
//			}
//		}
		generateInspectOtherItemData();
		PrimeFaces.current().executeScript("closeAndSave("+inspectOtherItemData+")");
	}
	/**
	 * 处理节点选中事件
	 * 由于页面中的treetable并未放置在form中，所以需手动添加
	 * @param event
	 */
	public void onNodeSelect(NodeSelectEvent event) {
		TreeNode selectedNode = event.getTreeNode();
//		selectedNodeList.add(selectedNode);
//		recursiveAddChildrenFromSelectedNodes(selectedNode);
//		recursiveAddParentFromSelectedNodes(selectedNode);
	}
	/**
	 * 循环往selectedNodes集合中添加selectedNode的子节点
	 * 添加的条件：该集合中不存在该节点
	 * @param selectedNode
	 */
//	private void recursiveAddChildrenFromSelectedNodes(TreeNode selectedNode) {
//		List<TreeNode> children = selectedNode.getChildren();
//		if(children!=null&&!children.isEmpty()) {
//			for(TreeNode node : children) {
//				if(!selectedNodeList.contains(node)) {
//					selectedNodeList.add(node);
//				}
//				recursiveAddChildrenFromSelectedNodes(node);
//			}
//		}
//	}
	/**
	 * 循环往selectedNodes集合中添加selectedNode的父节点
	 * 添加的条件：该父节点下所有的子节点都已存在在selectedNodes集合中
	 * @param selectedNode
	 */
//	private void recursiveAddParentFromSelectedNodes(TreeNode selectedNode) {
//		TreeNode parent = selectedNode.getParent();
//		if(parent!=null&&!parent.equals(root)) {
//			List<TreeNode> children = parent.getChildren();
//			for(TreeNode node : children) {
//				if(!selectedNodeList.contains(node)) {
//					return;
//				}
//			}
//			selectedNodeList.add(parent);
//			recursiveAddParentFromSelectedNodes(parent);
//		}
//	}
	/**
	 * 处理节点取消选中事件
	 * @param event
	 */
	public void onNodeUnselect(NodeUnselectEvent event) {
		TreeNode selectedNode = event.getTreeNode();
//		selectedNodeList.remove(selectedNode);
//		recursiveRemoveChildrenFromSelectedNodes(selectedNode);
//		recursiveRemoveParentFromSelectedNodes(selectedNode);
	}
	/**
	 * 循环从selectedNodes集合中移除selectedNode的子节点
	 * 移除的条件：该集合中存在这些子节点
	 * @param selectedNode
	 */
	private void recursiveRemoveChildrenFromSelectedNodes(TreeNode selectedNode) {
//		List<TreeNode> children = selectedNode.getChildren();
//		if(children!=null&&!children.isEmpty()) {
//			for(TreeNode node : children) {
//				if(selectedNodeList.contains(node)) {
//					selectedNodeList.remove(node);
//					recursiveRemoveChildrenFromSelectedNodes(node);
//				}
//			}
//		}
	}
	/**
	 * 循环从selectedNodes集合中移除selectedNode父节点
	 * 移除的条件：该集合中存在这个父节点
	 * @param selectedNode
	 */
	private void recursiveRemoveParentFromSelectedNodes(TreeNode selectedNode) {
//		TreeNode parent = selectedNode.getParent();
//		if(parent!=null) {
//			if(selectedNodeList.contains(parent)) {
//				selectedNodeList.remove(parent);
//				recursiveRemoveParentFromSelectedNodes(parent);
//			}
//		}
	}
	/**
	 * 生成要返回的数据：inspectOtherItemData
	 */
	private void generateInspectOtherItemData() {
		JSONObject r = new JSONObject();
		StringBuffer inspectionScope = new StringBuffer("");
		for(InspectionScopeModel model : selectedModels) {
			inspectionScope.append(model.getInspectionScope()).append("-");
			if(StringUtils.isNotBlank(model.getInspectionScopePersonnel())) {
				inspectionScope.append(model.getInspectionScopePersonnel());
			}else {
				inspectionScope.append("null");
			}
			inspectionScope.append("-");
			if(StringUtils.isNotBlank(model.getInspectionScopePersonnelPhone())) {
				inspectionScope.append(model.getInspectionScopePersonnelPhone());
			}else {
				inspectionScope.append("null");
			}
			inspectionScope.append(",");
		}
		inspectionScope.deleteCharAt(inspectionScope.lastIndexOf(","));
		r.put("inspectionScope", inspectionScope.toString());
		
//		r.put("inspectionScopePersonnel",inspectionScopePersonnel);
//		r.put("inspectionScopePersonnelPhone", inspectionScopePersonnelPhone);
		List<String> acceptUnits = new ArrayList<String>();
		for(int i=0;i<selectedNodes.length;i++) {
			TreeNode node = selectedNodes[i];
			if("unit".equals(node.getType())) {
				ManagementUnitDict unit = (ManagementUnitDict) node.getData();
				acceptUnits.add(unit.getId());
			}
		}
		r.put("acceptUnits", acceptUnits);
		inspectOtherItemData = r.toJSONString();
	}
	/**
	 * 派出分子公司联系人响应autocomplete集合
	 * @param model
	 * @return
	 */
	public List<String> completeInspectionScopePersonnels(String query) {
		List<String> result = new ArrayList<String>();
		List<PersonnelEntityBean> personnels = new ArrayList<PersonnelEntityBean>();
		InspectionScopeModel modelOnFocus = getModelOnFocus();
		if(StringUtils.isNotBlank(modelOnFocus.getInspectionScope())) {
			if(scopeNameToPersonnels.containsKey(modelOnFocus.getInspectionScope())) {
				personnels = scopeNameToPersonnels.get(modelOnFocus.getInspectionScope());
			}else {
				ManagementUnitDict unit = null;
				try {
					unit = unitService.getManagementUnitByName(modelOnFocus.getInspectionScope());
					if(unit!=null) {
						personnels = orgService.recursiveFindDepartPersonnels(unit.getId());
						scopeNameToPersonnels.put(modelOnFocus.getInspectionScope(), personnels);
					}
					for(PersonnelEntityBean personnel : personnels) {
						if(!personnelMap.containsKey(modelOnFocus.getInspectionScope()+"-"+personnel.getName())) {
							personnelMap.put(modelOnFocus.getInspectionScope()+"-"+personnel.getName(), personnel);
						}
					}
				} catch (ManagementUnitException e) {
					e.printStackTrace();
				}
			}
		}
		if(StringUtils.isNotBlank(query)) {
			for(PersonnelEntityBean personnel : personnels) {
				if(PingYinUtil.getPingYinHeader(personnel.getName()).startsWith(query)) {
					result.add(personnel.getName());
				}
			}
		}else {
			for(PersonnelEntityBean personnel : personnels) {
				result.add(personnel.getName());
			}
		}
		return result;
	}
	/**
	 * 派出分子公司联系人选中处理函数
	 * @param model
	 */
	public void onInspectionScopePersonnelSelect(InspectionScopeModel model) {
		if(StringUtils.isNotBlank(model.getInspectionScopePersonnel())) {
			String key = model.getInspectionScope()+"-"+model.getInspectionScopePersonnel();
			if(personnelMap.containsKey(key)) {
				PersonnelEntityBean selectedPersonnel = personnelMap.get(key);
				model.setInspectionScopePersonnelPhone(selectedPersonnel.getTelephone());
			}
		}
	}
	/**
	 * 获得当前操作的model
	 * @return
	 */
	private InspectionScopeModel getModelOnFocus() {
		FacesContext context = FacesContext.getCurrentInstance();
		InspectionScopeModel model = (InspectionScopeModel) UIComponent.getCurrentComponent(context).getAttributes().get("model");
		return model;
	}
	public String getSelectedScopeId() {
		return selectedScopeId;
	}
	public void setSelectedScopeId(String selectedScopeId) {
		this.selectedScopeId = selectedScopeId;
	}
	public String getInspectionScopePersonnel() {
		return inspectionScopePersonnel;
	}
	public void setInspectionScopePersonnel(String inspectionScopePersonnel) {
		this.inspectionScopePersonnel = inspectionScopePersonnel;
	}
	public String getInspectionScopePersonnelPhone() {
		return inspectionScopePersonnelPhone;
	}
	public void setInspectionScopePersonnelPhone(String inspectionScopePersonnelPhone) {
		this.inspectionScopePersonnelPhone = inspectionScopePersonnelPhone;
	}
	public List<ManagementUnitDict> getAllMaintenanceScopes() {
		return allMaintenanceScopes;
	}
	public void setAllMaintenanceScopes(List<ManagementUnitDict> allMaintenanceScopes) {
		this.allMaintenanceScopes = allMaintenanceScopes;
	}
	public TreeNode getRoot() {
		return root;
	}
	public void setRoot(TreeNode root) {
		this.root = root;
	}
	public TreeNode[] getSelectedNodes() {
		return selectedNodes;
	}
	public void setSelectedNodes(TreeNode[] selectedNodes) {
		this.selectedNodes = selectedNodes;
	}
	public String getInspectOtherItemData() {
		return inspectOtherItemData;
	}
	public void setInspectOtherItemData(String inspectOtherItemData) {
		this.inspectOtherItemData = inspectOtherItemData;
	}
	public List<InspectionScopeModel> getModels() {
		return models;
	}
	public void setModels(List<InspectionScopeModel> models) {
		this.models = models;
	}
	public List<InspectionScopeModel> getSelectedModels() {
		return selectedModels;
	}
	public void setSelectedModels(List<InspectionScopeModel> selectedModels) {
		this.selectedModels = selectedModels;
	}
	
}
